﻿using ASmile.CodeFactory.DaBLL.Builder;
using ASmile.CodeFactory.DBModel;
using ASmile.Extend;
using ASmile.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ASmile.CodeFactory.DaBLL
{
    class RemarkBLL : DaMain
    {
        /// <summary>
        /// 获取配置
        /// </summary>
        public ApiResultList<TConfig> GetConfigs(ArgPageData arg)
        {
            return new ConfigBLL().GetList(arg);
        }
        /// <summary>
        /// 获取表
        /// </summary>
        public ApiResultList<TTableRemark> GetTables(string configId, string tableType, int hideState, string searchVal)
        {
            var rList =
            DB.Query<TTableRemark>(query =>
            {
                query.WhereAnd(s => s.ConfigId == configId && s.TableType == tableType);
                if (hideState == 1)
                {
                    query.WhereAnd(s => s.IsHide == false);
                }
                else if (hideState == 2)
                {
                    query.WhereAnd(s => s.IsHide == true);
                }
                if (searchVal.IsNotEmpty())
                {
                    string likeStr = $"%{searchVal}%";
                    query.WhereAnd(s =>
                        s.WEx_Like(s.TableName, likeStr) ||
                        s.WEx_Like(s.RemarkSelf, likeStr) ||
                        s.WEx_Like(s.RemarkSrc, likeStr));
                }
                query.OrderBy(s => s.TableName);
            }).ToList();
            return RetOK(rList, 0);
        }

        public ApiResult SyncDbObject(TConfig config, EmTableType tbType)
        {
            switch (tbType)
            {
                case EmTableType.Table:
                    return SyncTable(config);
                case EmTableType.View:
                    return SyncView(config);
                case EmTableType.Proc:
                    return SyncProc(config);
                default:
                    return RetErr("错误的类型");
            }
        }
        /// <summary>
        /// 从数据库中同步表信息
        /// </summary>
        public ApiResult SyncTable(TConfig config)
        {
            var builder = BuilderFactory.Create(config, true);
            var dbTables = builder.GetTables(true);
            bool isNew;
            string tbType = EmTableType.Table.ToString();
            foreach (var item in dbTables)
            {
                isNew = false;
                var m = DB.Query<TTableRemark>(s => s.ConfigId == config.Id && s.TableType == tbType && s.TableName == item.TableName).ToEntity();
                if (m == null)
                {
                    m = new TTableRemark
                    {
                        Id = NewId(),
                        TableType = tbType,
                        ConfigId = config.Id,
                        TableName = item.TableName,
                        IsHide = false,
                        RemarkSelf = item.TableRemark,
                        RemarkSrc = item.TableRemark
                    };
                    isNew = true;
                }
                if (isNew)
                {
                    DB.Insert(m);
                }
                else if (!m.RemarkSrc.StringEquals(item.TableRemark))
                {
                    if (m.RemarkSelf.IsEmpty())
                    {
                        m.RemarkSelf = item.TableRemark;
                    }
                    m.RemarkSrc = item.TableRemark;
                    DB.Update(m);
                }
            }
            var allTables = dbTables.Select(s => s.TableName).ToArray();
            DB.Delete<TTableRemark>(s =>
                s.ConfigId == config.Id &&
                s.TableType == tbType &&
                s.WEx_InNot(s.TableName, allTables));
            return RetOK("同步成功");
        }
        /// <summary>
        /// 从数据库中同步视图信息
        /// </summary>
        public ApiResult SyncView(TConfig config)
        {
            var builder = BuilderFactory.Create(config, true);
            var dbViews = builder.GetViews();
            string tbType = EmTableType.View.ToString();
            foreach (var item in dbViews)
            {
                if (DB.QueryExist<TTableRemark>(s => s.ConfigId == config.Id && s.TableType == tbType && s.TableName == item.TableName))
                {
                    continue;
                }
                var m = new TTableRemark
                {
                    Id = NewId(),
                    TableType = tbType,
                    ConfigId = config.Id,
                    TableName = item.TableName,
                    IsHide = false,
                    RemarkSelf = item.TableRemark,
                    RemarkSrc = item.TableRemark
                };
                DB.Insert(m);
            }
            var allTables = dbViews.Select(s => s.TableName).ToArray();
            DB.Delete<TTableRemark>(s =>
                s.ConfigId == config.Id &&
                s.TableType == tbType &&
                s.WEx_InNot(s.TableName, allTables));
            return RetOK("同步成功");
        }
        /// <summary>
        /// 从数据库中同步存储过程信息
        /// </summary>
        public ApiResult SyncProc(TConfig config)
        {
            var builder = BuilderFactory.Create(config, true);
            var dbProcs = builder.GetProcs(true);
            var tbType = EmTableType.Proc.ToString();
            foreach (var item in dbProcs)
            {
                if (DB.QueryExist<TTableRemark>(s => s.ConfigId == config.Id && s.TableType == tbType && s.TableName == item.ProcName))
                {
                    continue;
                }
                var m = new TTableRemark
                {
                    Id = NewId(),
                    TableType = tbType,
                    ConfigId = config.Id,
                    TableName = item.ProcName,
                    IsHide = false,
                };
                DB.Insert(m);
            }
            var allTables = dbProcs.Select(s => s.ProcName).ToArray();
            DB.Delete<TTableRemark>(s =>
                s.ConfigId == config.Id &&
                s.TableType == tbType &&
                s.WEx_InNot(s.TableName, allTables));

            return RetOK("OK");
        }
        /// <summary>
        /// 获取指定表、视图或存储过程 字段(参数)
        /// </summary>
        public ApiResultList<TFieldRemark> GetFields(TTableRemark table)
        {
            if (table == null)
            {
                return RetNullData<TFieldRemark>("参数为空");
            }
            var rList =
            DB.Query<TFieldRemark>(query =>
            {
                query.WhereAnd(s => s.ConfigId == table.ConfigId && s.TableName == table.TableName);
                query.OrderBy(s => s.FieldNo);
            }).ToList();
            return RetOK(rList, 0);
        }
        /// <summary>
        /// 同步表与视图的字段
        /// </summary>
        ApiResult SyncTableField(TTableRemark table)
        {
            var config = DB.Query<TConfig>(s => s.Id == table.ConfigId).ToEntity();
            if (config == null)
            {
                return RetErr("配置不存在");
            }
            var builder = BuilderFactory.Create(config, true);
            var dbFields = builder.GetTableColumns(table.TableName, true);
            //var dbProcFileds = builder.GetProcParam(table.TableName);
            bool isNew;
            foreach (var item in dbFields)
            {
                isNew = false;
                var m = DB.Query<TFieldRemark>(s => s.ConfigId == config.Id && s.TableName == table.TableName && s.FieldName == item.ColumnName).ToEntity();
                if (m == null)
                {
                    m = new TFieldRemark
                    {
                        Id = NewId(),
                        ConfigId = config.Id,
                        TableType = table.TableType,
                        TableName = item.TableName,
                        IsHide = false,
                        FieldNo = item.ColumnIndex,
                        FieldName = item.ColumnName,
                        RemarkSelf = item.ColumnRemark,
                        RemarkSrc = item.ColumnRemark
                    };
                    isNew = true;
                }
                if (isNew)
                {
                    DB.Insert(m);
                }
                else
                {
                    if (!m.RemarkSrc.StringEquals(item.ColumnRemark))
                    {
                        m.RemarkSrc = item.ColumnRemark;
                    }
                    if (m.RemarkSelf.IsEmpty())
                    {
                        m.RemarkSelf = item.ColumnRemark;
                    }
                    if (m.FieldNo != item.ColumnIndex)
                    {
                        m.FieldNo = item.ColumnIndex;
                    }
                    if (m.HasChangedField())
                    {
                        DB.Update(m);
                    }
                }
            }

            var allFiles = dbFields.Select(s => s.ColumnName).ToArray();

            DB.Delete<TFieldRemark>(s =>
                s.ConfigId == config.Id &&
                s.TableName == table.TableName &&
                s.WEx_InNot(s.FieldName, allFiles));
            return RetOK("OK");
        }
        /// <summary>
        /// 同步表与视图的字段
        /// </summary>
        ApiResult SyncProcField(TTableRemark table)
        {
            var config = DB.Query<TConfig>(s => s.Id == table.ConfigId).ToEntity();
            if (config == null)
            {
                return RetErr("配置不存在");
            }
            var builder = BuilderFactory.Create(config, true);
            var dbProcFileds = builder.GetProcParam(table.TableName, true);
            bool isNew;

            foreach (var item in dbProcFileds)
            {
                isNew = false;
                var m = DB.Query<TFieldRemark>(s => s.ConfigId == config.Id && s.TableName == table.TableName && s.FieldName == item.ParamName).ToEntity();
                if (m == null)
                {
                    m = new TFieldRemark
                    {
                        Id = NewId(),
                        ConfigId = config.Id,
                        TableType = table.TableType,
                        TableName = table.TableName,
                        IsHide = false,
                        FieldNo = item.ParamIndex,
                        FieldName = item.ParamName,
                    };
                    isNew = true;
                }
                if (isNew)
                {
                    DB.Insert(m);
                }
                else
                {
                    if (m.FieldNo != item.ParamIndex)
                    {
                        m.FieldNo = item.ParamIndex;
                    }
                    if (m.HasChangedField())
                    {
                        DB.Update(m);
                    }
                }
            }

            var allFiles = dbProcFileds.Select(s => s.ParamName).ToArray();
            DB.Delete<TFieldRemark>(s =>
                s.ConfigId == config.Id &&
                s.TableName == table.TableName &&
                s.WEx_InNot(s.FieldName, allFiles));

            return RetOK("OK");
        }
        /// <summary>
        /// 同步
        /// </summary>
        public ApiResult SyncField(TTableRemark m)
        {
            if (EnumHelper.StringToEnum<EmTableType>(m.TableType, out EmTableType tbType))
            {
                switch (tbType)
                {
                    case EmTableType.Table:
                    case EmTableType.View:
                        return SyncTableField(m);
                    case EmTableType.Proc:
                        return SyncProcField(m);
                }
            }
            return RetErr("错误的配置");
        }
        /// <summary>
        /// 设置字段备注
        /// </summary>
        public ApiResult<string> SetFieldRemark(TFieldRemark m)
        {
            //if (m.RemarkSelf.IsEmpty())
            //{
            //    return RetErr("RemarkSelf", "备注不能为空");
            //}
            DB.Update(m);
            return RetOK("", "OK");
        }
        /// <summary>
        /// 设置表备注
        /// </summary>
        public ApiResult<string> SetTableRemark(TTableRemark m)
        {
            //if (m.RemarkSelf.IsEmpty())
            //{
            //    return RetErr("RemarkSelf", "备注不能为空");
            //}
            DB.Update(m);
            return RetOK("", "OK");
        }

        public ApiResult SetTableHide(TTableRemark m, bool isHide)
        {
            m.IsHide = isHide;
            DB.Update(m);
            var str = isHide ? "隐藏" : "可见";
            return RetOK($"设置 {m.TableName} {str} 成功");
        }

        public ApiResult SetFieldHide(TFieldRemark m, bool isHide)
        {
            m.IsHide = isHide;
            DB.Update(m);
            var str = isHide ? "隐藏" : "可见";
            return RetOK($"设置 {m.FieldName} {str} 成功");
        }
    }
}